package za.org.jcicada.genss.alarm.impl;

import java.util.Set;

import za.org.jcicada.comms.IConnection;
import za.org.jcicada.comms.impl.MessagingBase;
import za.org.jcicada.genss.ServiceURN;
import za.org.jcicada.genss.alarm.AlarmURN;
import za.org.jcicada.genss.alarm.IAlarm;
import za.org.jcicada.genss.alarm.IAlarmObserver;
import za.org.jcicada.genss.alarm.IAlarmSubject;
import za.org.jcicada.genss.alarm.messages.AcknowledgeAlarmReply;
import za.org.jcicada.genss.alarm.messages.AlarmInform;
import za.org.jcicada.genss.alarm.messages.AlarmSetReply;
import za.org.jcicada.genss.alarm.messages.AttachReply;
import za.org.jcicada.genss.alarm.messages.DetachReply;
import za.org.jcicada.genss.alarm.messages.ReportReply;
import za.org.jcicada.genss.messages.Result;
import za.org.jcicada.genss.messages.TerminateServiceInform;

public class AlarmMessaging extends MessagingBase {

    /**
     * Handle to alarm subject for invoking methods on.
     */
    IAlarmSubject alarmSubject;

    /**
     * Handle to callback object for messages from the subject to the observer.
     */
    IAlarmObserver alarmObserver;

    public AlarmMessaging(IConnection connection, IAlarmSubject alarmSubject) {
        super(connection);
        this.alarmSubject = alarmSubject;
        alarmObserver = new Responder();
    }

    public void onClose() throws Exception {
        alarmSubject.informDisconnect(alarmObserver);
    }

    /**
     * Dispatch AttachRequest.
     */
    public void alarmAttachRequest(za.org.jcicada.genss.alarm.messages.AttachRequest msg) {
        alarmSubject.requestAttach(alarmObserver);
    }

    /**
     * Dispatch DetachRequest.
     */
    public void alarmDetachRequest(za.org.jcicada.genss.alarm.messages.DetachRequest msg) {
        alarmSubject.requestDetach(alarmObserver);
    }

    /**
     * Dispatch AlarmSetRequest.
     */
    public void alarmAlarmSetRequest(za.org.jcicada.genss.alarm.messages.AlarmSetRequest msg) {
        alarmSubject.requestAlarmSet(alarmObserver);
    }

    /**
     * Dispatch ReportRequest.
     */
    public void alarmReportRequest(za.org.jcicada.genss.alarm.messages.ReportRequest msg) {
        alarmSubject.requestReport(alarmObserver);
    }

    /**
     * Dispatch AcknowledgeAlarmRequest.
     */
    public void alarmAcknowledgeAlarmRequest(za.org.jcicada.genss.alarm.messages.AcknowledgeAlarmRequest msg) {
        alarmSubject.requestAcknowledgeAlarm(alarmObserver, msg.getAlarmURN());
    }

    /**
     * Implementation of IAlarmObserver that sends messages back to a katcomms
     * connection.
     */
    public class Responder extends MessagingBase.ResponderBase implements IAlarmObserver {

        /**
         * Called after attaching to a list of sensors using IAlarmSubject.attach().
         */
        public void replyAttach(Result result) {
            sendMessage(new AttachReply(result));
        }

        /**
         * Called after detaching from a list of sensors using IAlarmSubject.detach().
         */
        public void replyDetach(Result result) {
            sendMessage(new DetachReply(result));
        }

        /**
         * Called after requesting the list of alarms using IAlarmSubject.requestAlarmSet().
         */
        public void replyAlarmSet(Result result, Set<AlarmURN> alarmURNs) {
            sendMessage(new AlarmSetReply(result, alarmURNs));
        }

        /**
         * Called after requesting a report using IAlarmSubject.requestReport().
         */
        public void replyReport(Result result, String report) {
            sendMessage(new ReportReply(result, report));
        }

        /**
         * Called after acknowledging an alarm using IAlarmSubject.requestAcknowledgeAlarm().
         */
        public void replyAcknowledgeAlarm(Result result, AlarmURN alarmURN) {
            sendMessage(new AcknowledgeAlarmReply(result, alarmURN));
        }

        // inform messages

        /**
         * Notify the observer of a change in the status of an alarm.
         */
        public void informAlarm(AlarmURN alarmURN, IAlarm alarm) {
            sendMessage(new AlarmInform(alarmURN, alarm));
        }

        /**
         * Notify the observer that its attachment has been terminated.
         */
        public void informTerminateService(ServiceURN serviceURN) {
            sendMessage(new TerminateServiceInform(serviceURN));
        }

    }
}
